package org.java.auth.web;

import org.java.auth.conf.JwtProperties;
import org.java.auth.pojo.UserInfo;
import org.java.auth.service.AuthService;
import org.java.auth.utils.JwtUtils;
import org.java.common.util.CookieUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author WHQ
 * @version 1.0
 * @date 2022-3-11 0011 下午 7:28
 */
@RestController
//先加载属性类(用于加载属性类，将yml文件中的配置信息读入到属性类中，并且将属性类加载到Spring容器中)
@EnableConfigurationProperties(JwtProperties.class)
public class AuthController {
    @Autowired
    private AuthService authService;
    @Autowired
    private JwtProperties jwtProperties;
    /**
     * 用户登录的方法,无返回值
     * 访问地址:http://api.shopping.com/auth/login
     * @param username
     * @param password
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/login")
    public ResponseEntity<Void> login(@RequestParam("username")String username,
                                      @RequestParam("password")String password,
                                      HttpServletRequest request, HttpServletResponse response){
        String token=authService.login(username,password);
        if (token==null){
            //信息错误，登录失败,返回无效参数的状态码
            return ResponseEntity.badRequest().build();
        }
        //信息正确,要将生成的token令牌通过cookie发送到客户端保存
        //通过shopping-common模块下面的cookieUtils工具类就可以向客户端发送cookie
        /**
         * 设置cookie需要五个参数:
         * request:在方法中直接注入
         * response
         * cookie的名称:从属性类中获取
         * cookie的值:token
         * cookie的有效时间(单位秒):属性类中，默认为分钟，变为秒钟需要*60
         * 下面的方法只要执行，cookie就会发送到客户端存储起来
         */
        System.out.println("token====="+token);
        CookieUtils.setCookie(request,response,jwtProperties.getCookieName(),token,jwtProperties.getExpire()*60);
//        返回状态码200，标识登录成功
        return ResponseEntity.ok().build();
    }

    /**
     * 验证用户是否登录的方法
     * 访问地址:http://api.shopping.com/auth/verify
     * @param token
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/verify")
    public ResponseEntity<UserInfo> verify(@CookieValue("shopping-token") String token,
                                           HttpServletRequest request,
                                           HttpServletResponse response){
        System.out.println("返回回来的token:"+token);
        if (StringUtils.isEmpty(token)){
            //token为空，返回认证失败
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        //不为空，继续验证token是否正确
        try {
            //获取成功，token正确
            UserInfo userInfo = JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey());
            System.out.println(userInfo.getUsername());
            //重新生成token
            token = JwtUtils.generateToken(userInfo, jwtProperties.getPrivateKey(), jwtProperties.getExpire());
            //重新产生cookie，并且重新设置过期时间,发送到客户端，覆盖之前的cookie
            /**
             * 1.请求---方法接收
             * 2.响应
             * 3.cookie名称----jwtProperties属性类中有
             * 4.token--------token
             * 5.过期时间----单位秒
             */
            CookieUtils.setCookie(request,response,jwtProperties.getCookieName(),token,jwtProperties.getExpire()*60);
            //解析成功，返回userInfo
            return ResponseEntity.ok(userInfo);
        } catch (Exception e) {
            e.printStackTrace();
            //获取出现异常
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
    }

    /**
     * 退出的方法
     * 访问地址:http://api.shopping.com/auth/logout
     * @param token
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public ResponseEntity<Void> logout(@CookieValue(name = "shopping-token")String token,
                                       HttpServletRequest request,
                                       HttpServletResponse response){
        System.out.println("进入退出登录的方法:"+token);
        //通过cookieUtils向客户端发送一个cookie，并且让这个cookie覆盖之前的cookie，并且马上过期
        /**
         * 1.请求
         * 2.响应
         * 3.cookie的名称----jwtProperties属性类中
         * 4.cookie的值------接收进来的token
         * 5.有效时间(单位秒)---1s
         */
        CookieUtils.setCookie(request,response,jwtProperties.getCookieName(),token,1);
        return ResponseEntity.ok().build();
    }
}
